package com.valuablecode.test;

import java.util.*;

/**
 * Knows how to create dates from the Gregorian calendar using an English-like syntax.
 * 
 * <p> Typical usage in test code is:
 * <blockquote><pre>
 * assertThat(billingPolicy.currentMonthEnd(), equalTo(april(30, 2010)));</pre></blockquote>
 * 
 * @author Alistair McKinnell
 */
public class DateFactory {
    
    private static final int DEFAULT_YEAR = 2010;
    
    public static Date now() {
        return new Date();
    }

    public static Date january(int dayOfMonth) {
        return january(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date january(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.JANUARY, year);
    }

    public static Date february(int dayOfMonth) {
        return february(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date february(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.FEBRUARY, year);
    }

    public static Date march(int dayOfMonth) {
        return march(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date march(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.MARCH, year);
    }

    public static Date april(int dayOfMonth) {
        return april(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date april(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.APRIL, year);
    }

    public static Date may(int dayOfMonth) {
        return may(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date may(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.MAY, year);
    }

    public static Date june(int dayOfMonth) {
        return june(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date june(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.JUNE, year);
    }

    public static Date july(int dayOfMonth) {
        return july(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date july(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.JULY, year);
    }

    public static Date august(int dayOfMonth) {
        return august(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date august(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.AUGUST, year);
    }

    public static Date september(int dayOfMonth) {
        return september(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date september(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.SEPTEMBER, year);
    }
    
    public static Date october(int dayOfMonth) {
        return october(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date october(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.OCTOBER, year);
    }
    
    public static Date november(int dayOfMonth) {
        return november(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date november(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.NOVEMBER, year);
    }
    
    public static Date december(int dayOfMonth) {
        return december(dayOfMonth, DEFAULT_YEAR);
    }
    
    public static Date december(int dayOfMonth, int year) {
        return createCalendar(dayOfMonth, Calendar.DECEMBER, year);
    }
    
    private static Date createCalendar(int dayOfMonth, int month, int year) {
        return new GregorianCalendar(year, month, dayOfMonth).getTime();
    }

}
